#!/bin/bash

if [ $UID -ne 0 ]; then
	echo "this scripts must be run with root"
	exit
fi

if [ $# -lt 4 ]; then
	echo "Usage: $0 <image_file> <fill_pattern> <image_size> <fs_type> [rootfs_tarball]"
	exit
fi

chkerr ()
{
	if [ $? -ne 0 ]; then
		echo "$1"
		exit 1
	else
		return 0	
	fi
}

build_fsimg ()
{
	echo "Making $1... ";
	local loop_dev="${LOOPDEV:-/dev/loop0}";
	if [ -e "${loop_dev}" ] && [ ! -b "${loop_dev}" ]; then
		echo "${loop_dev} is not block device. Terminating..";
		exit 1;
	fi
	loop_dev=`losetup --find`;
	if [ $? -ne 0 ]; then
		echo "Cannot find loop device. Terminating..";
		exit 1;
	fi
	umount "${loop_dev}" > /dev/null 2>&1;
	losetup -d "${loop_dev}" > /dev/null 2>&1;
	rm -f $1;	chkerr "clearing $1 failed.";
	rm -rf mnt;	chkerr "clearing $4 mount point failed.";

	local bcnt=$(( $3 / 512 ));
	local bcntdiv=$(( $3 % 512 ));
	if [ $bcnt -eq 0 -o $bcntdiv -ne 0 ]; then
		echo "Error: $4 file system size has to be 512 bytes allign.";
		exit 1;
	fi
	if [ "$2" != "" -a "$2" != "0" ]; then
		local fc=`printf '%d' $2`;
		local fillc=`printf \\\\$(printf '%02o' $fc)`;
		< /dev/zero head -c $3 | tr '\000' ${fillc} > $1;
		chkerr "making $1 with fillpattern(${fillc}) failed.";
	else
		truncate --size $3 $1;
		chkerr "making $1 with zero fillpattern failed.";
	fi
	losetup "${loop_dev}" $1 > /dev/null 2>&1;
	chkerr "mapping $1 to loop device failed.";

	echo "Partitioning ${loop_dev}"
	echo "making 256M /boot and other space as /"
	parted -a optimal -s ${loop_dev} -- mklabel msdos \
	unit MiB \
	mkpart primary 1 256 \
	mkpart primary 256 -1 

	chkerr "partition failed"

	echo "making fs $4 ..."
	if [ "$4" = "FAT32" ]; then
		mkfs.msdos -I -F 32 "${loop_dev}"p1
		mkfs -t $4 "${loop_dev}"p2 
	else
		mkfs -t $4 "${loop_dev}"p1 
		mkfs -t $4 "${loop_dev}"p2 
	fi
	chkerr "formating $4 filesystem on $1 failed.";
	mkdir -p mnt;			chkerr "make / mount point failed.";
	mount "${loop_dev}"p2 mnt;	chkerr "mount / failed.";
	mkdir -p mnt/boot;		chkerr "make /boot mount point failed.";
	mount "${loop_dev}"p1 mnt/boot;	chkerr "mount /boot failed.";

	echo "$1 partition (${loop_dev}p2) mounted on $PWD/mnt"
	echo "$1 partition (${loop_dev}p1) mounted on $PWD/mnt/boot"

	if [ "$5" != "" ]; then
		echo -e "\tpopulating rootfs from $5 ... ";
		tar -C mnt -xpf $5
		chkerr "extracting $5 failed"
	else
		echo "You must mount $1 manually and setup rootfs later"
		echo "sample command:"
		echo "sudo losetup -P loop_dev"
		echo "sudo mount loop_dev <mount point>"
	fi;

	echo -e -n "\tSync'ing $1 ... ";
	sync; sync; sleep 5;	# Give FileBrowser time to terminate gracefully.
	echo "done.";
	umount "${loop_dev}"p1 > /dev/null 2>&1;
	umount "${loop_dev}"p2 > /dev/null 2>&1;
	losetup -d "${loop_dev}" > /dev/null 2>&1;
	rmdir mnt > /dev/null 2>&1;

	echo "$1 built successfully. ";
}


################ main start here ##########################
rootfs_size=0

if [[ "$3" =~ G$ ]]; then
	num=${3%%G}
	rootfs_size=$((num * 1024 * 1024 * 1024)) 
elif [[ "$3" =~ M$ ]]; then
	num=${3%%M}
	rootfs_size=$((num * 1024 * 1024)) 
else
	rootfs_size=$3
	
fi

build_fsimg $1 $2 "${rootfs_size}" $4 $5
